/**
@file
Contains Trim functions.

Version:
0.1.0

Last updated date:
2012-08-09
*/


#pragma once
#include <string>


namespace Zaf {
namespace String {

#define __Zaf_Trim_DefaultBlankCharsA__ (" \t\r\n")
#define __Zaf_Trim_DefaultBlankCharsW__ (L" \t\r\n")


/**
Remove all specified characters at string's head and tail.

@param str %String to be trimmed.
@param chars Characters to be removed.

The modification is applied to \a str in place.
 */
template<typename CharType>
inline void Trim(std::basic_string<CharType>& str, const CharType* const chars) {
	str.erase(str.find_last_not_of(chars) + 1);
	str.erase(0, str.find_first_not_of(chars));
}

/**
Remove all blank characters at string's head and tail.

@param str %String to be trimmed.

Blank characters are: ' ', '\\t', '\\r' and '\\n'.

@see Trim(std::basic_string<CharType>&, const CharType* const)
 */
template<typename CharType>
inline void Trim(std::basic_string<CharType>& str);

template<>
inline void Trim<char>(std::string& str) {
	Trim(str, __Zaf_Trim_DefaultBlankCharsA__);
}

template<>
inline void Trim<wchar_t>(std::wstring& str) {
	Trim(str, __Zaf_Trim_DefaultBlankCharsW__);
}



/**
Remove all specified characters at string's head and tail,
and return a new string.

@param str %String to be trimmed.
@param chars Characters to be removed.
@return New string after trimmed.

No modification is applied to \a str.

@see Trim(std::basic_string<CharType>&, const CharType* const)
 */
template<typename CharType>
inline std::basic_string<CharType> Trim(const std::basic_string<CharType>& str, const CharType* const chars) {
	int beginIndex = str.find_first_not_of(chars);
	if (beginIndex == -1) {
		return std::basic_string<CharType>();
	}
	int endIndex = str.find_last_not_of(chars) + 1;
	return str.substr(beginIndex, endIndex - beginIndex);
}



/**
Remove all blank characters at string's head and tail,
and return a new string.

@param str %String to be trimmed.
@return New string after trimmed.

@see Trim(const std::basic_string<CharType>&, const CharType* const)
@see Trim(std::basic_string<CharType>&)
*/
template<typename CharType>
inline std::basic_string<CharType> Trim(const std::basic_string<CharType>& str);

template<>
inline std::string Trim<char>(const std::string& str) {
	return Trim(str, __Zaf_Trim_DefaultBlankCharsA__);
}

template<>
inline std::wstring Trim<wchar_t>(const std::wstring& str) {
	return Trim(str, __Zaf_Trim_DefaultBlankCharsW__);
}


}
}